package com.shadow.demo.shiro.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.shadow.demo.common.constants.PunctuationConstants;
import com.shadow.demo.common.enums.shiro.PCodeEnum;
import com.shadow.demo.common.enums.shiro.ShiroStatusEnum;
import com.shadow.demo.data.bo.Query;
import com.shadow.demo.data.shiro.entity.Role;
import com.shadow.demo.data.shiro.entity.UserRole;
import com.shadow.demo.data.shiro.mapper.RoleMapper;
import com.shadow.demo.data.shiro.mapper.UserRoleMapper;
import com.shadow.demo.shiro.util.UserUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RoleService extends BaseService<RoleMapper, Role> implements IService<Role> {

    @Resource
    private RoleMapper roleMapper;
    @Resource
    private UserRoleMapper userRoleMapper;

    public List<Role> getAllRoleList() {
        return roleMapper.selectList(null);
    }

    /**
     * 通过角色名称获取角色列表
     *
     * @param roleNameList 角色名称列表
     * @return {@link List} 角色列表
     * */
    public List<Role> getByNameList(final List<String> roleNameList) {
        if (CollectionUtils.isNotEmpty(roleNameList)) {
            LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<Role>()
                    .in(Role::getName, roleNameList);
            return roleMapper.selectList(wrapper);
        }
        return Collections.emptyList();
    }

    /**
     * 通过用户获取角色列表
     *
     * @param userId 用户id
     * @return {@link List} 角色列表
     * */
    public List<Role> getRoleListByUserId(String userId) {
        LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId);
        List<UserRole> userRoleList = userRoleMapper.selectList(userRoleWrapper);
        if (CollectionUtils.isNotEmpty(userRoleList)) {
            LambdaQueryWrapper<Role> roleWrapper = new LambdaQueryWrapper<Role>()
                    .in(Role::getId, userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
            return Collections.unmodifiableList(roleMapper.selectList(roleWrapper));
        }
        return Collections.emptyList();
    }

    /**
     * 获取所有可用的角色列表
     *
     * @return {@link List<Role>}
     * */
    public List<Role> getAvailableList() {
        final LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<Role>()
                .eq(Role::getStatus, ShiroStatusEnum.NOR.getStatus())
                .orderByDesc(Role::getName);
        return roleMapper.selectList(wrapper);
    }

    /**
     * 分页获取角色列表
     *
     * @param params 查询参数
     * @return {@link Role}
     * */
    public Page<Role> getList(final Map<String, Object> params) {
        final String name = (String) params.get("name");
        final LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<Role>()
                .eq(!UserUtils.hasPermissions(PCodeEnum.ROLE_DEL_SELECT.getCode()), Role::getStatus, 1)
                .like(StringUtils.isNotBlank(name), Role::getName, name)
                .orderByDesc(Role::getName);
        return roleMapper.selectPage(new Query<Role>(params).getPage(), wrapper);
    }

    /**
     * 验证存在性
     *
     * @param code 角色码
     * @return 是否存在 false 不存在 true 存在
     * */
    public boolean verifyExist(final String code) {
        if (StringUtils.isBlank(code)) {
            throw new IllegalArgumentException("角色码为空");
        }
        Long count = roleMapper.selectCount(new LambdaQueryWrapper<Role>().eq(Role::getCode, code));
        return count > 0L;
    }

    /**
     * 验证是否可以编辑
     *
     * @param id 角色id
     * @return 是否可以编辑 false 不 true 可
     * */
    public boolean verifyEditable(final String id) {
        if (StringUtils.isBlank(id)) {
            throw new IllegalArgumentException("未知角色");
        }
        Role role = getById(id);
        return role != null && role.getStatus() == 1;
    }

    /**
     * 逻辑删除
     * @param ids 以逗号分割的id
     * */
    public int delete(final String ids) {
        String[] split = ids.split(PunctuationConstants.SPLIT_COMMA);
        if (ArrayUtils.isEmpty(split)) {
            return 0;
        }
        LambdaUpdateWrapper<Role> updateWrapper = new LambdaUpdateWrapper<Role>()
                .set(Role::getStatus, "0")
                .in(Role::getId, Arrays.asList(split));
        return roleMapper.update(updateWrapper);
    }
}
